package com.panopset.gui;

import static com.panopset.Util.*;
import static com.panopset.UtilIO.*;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.panopset.Strings;
import com.panopset.io.JarResources;

/**
 * Collection of like small images.
 *
 * @author Karl Dinwiddie
 *
 */
public final class SpritePackage {

    /**
     * Jar path.
     */
    private final String jarPath;

    /**
     *
     * @param path
     *            Path to jar containing .png images
     */
    public SpritePackage(final String path) {
        jarPath = path;
    }

    @Override
    public String toString() {
        return getList();
    }

    /**
     * Jar resources.
     */
    private JarResources jarResources;

    /**
     * @return Jar resources.
     */
    public JarResources getJarResources() {
        if (jarResources == null) {
            jarResources = new JarResources(getJarFile());
        }
        return jarResources;
    }

    /**
     * Resource list.
     */
    private Vector<String> resourceList;

    /**
     * @return Resource list.
     */
    public Vector<String> getResourceList() {
        if (resourceList == null) {
            resourceList = new Vector<String>();
            try {
                for (String k : getJarResources().getSizes().keySet()) {
                    String name = dropPath(k);
                    if (isPopulated(name) && name.indexOf(".png") > -1) {
                        resourceList.add(dropExtension(name));
                    }
                }
            } catch (IOException e) {
                log(e);
            }
        }
        return resourceList;
    }

    /**
     * @return List of resources.
     */
    private String listResources() {
        StringWriter sw = new StringWriter();
        for (String name : getResourceList()) {
            sw.append(name);
            sw.append(Strings.getEol());
        }
        return sw.toString();
    }

    /**
     * Save all images to a directory.
     *
     * @param targetPath
     *            path to directory, either full or relative to runtime.
     * @throws IOException
     *             IO Exception.
     */
    public void saveImagesToDirectory(final String targetPath)
            throws IOException {
        saveImagesToDirectory(targetPath, null);
    }

    /**
     * Save images, that match a filter, to a directory.
     *
     * @param targetPath
     *            path to directory, either full or relative to runtime.
     * @param filter
     *            Vector<String> only save those resources that are in this
     *            filter Vector. Extensions ignored if provided.
     * @throws IOException
     *             IO Exception.
     */
    public void saveImagesToDirectory(final String targetPath,
            final Vector<String> filter) throws IOException {
        for (String k : getJarResources().getSizes().keySet()) {
            String name = dropPath(k);
            if (isPopulated(name) && name.indexOf(".png") > -1) {
                saveFilteredResource(targetPath, filter, k, name);
            }
        }
    }

    /**
     * Save filtered resource.
     *
     * @param targetPath Target path.
     * @param filter Filter.
     * @param k Jar resources key.
     * @param name Name.
     * @throws IOException IO Exception.
     */
    private void saveFilteredResource(final String targetPath,
            final Vector<String> filter, final String k, final String name)
            throws IOException {
        if (filter == null || filter.contains(dropExtension(name))
                || filter.contains(name)) {
            saveBytesToFile(getJarResources().getResource(k), new File(
                    targetPath + "/" + name));
        }
    }

    /**
     * Jar file.
     */
    private File jarFile;

    /**
     * The package jar is saved in ${user.home}/.panopset for extraction.
     *
     * @return work File where jar is saved.
     */
    public File getJarFile() {
        if (jarFile == null) {
            String panopsetWorkDirectoryPath = System.getProperty("user.home")
                    + "/.panopset";
            try {
                jarFile = savePackageResource(jarPath,
                        panopsetWorkDirectoryPath);
            } catch (IOException ex) {
                log("jarPath: " + jarPath);
                log("panopsetWorkDirectoryPath: " + panopsetWorkDirectoryPath);
                Logger.getLogger(SpritePackage.class.getName()).log(
                        Level.SEVERE, null, ex);
            }
        }
        return jarFile;
    }

    /**
     * List.
     */
    private String list;

    /**
     *
     * @return list of names of each sprite .png image.
     */
    private String getList() {
        if (list == null) {
            list = listResources();
        }
        return list;
    }

}
